#ifndef PSD_SETTINGS_H
#define PSD_SETTINGS_H

#include "libconfig.h"

enum psd_setting_types { PSD_SETTING_STRING, PSD_SETTING_BOOL, PSD_SETTING_INT, PSD_SETTING_LIST };

typedef struct psd_settings_t {
	config_t root;
} psdSettings;

typedef struct psd_setting_desc_t {
	char *name;
	enum psd_setting_types type;
} psdSettingDesc;

inline int psd_settings_get(const psdSettings *settings, const char *setting, char **value);
inline int psd_settings_get_int(const psdSettings *settings, const char *setting, int *value);
inline int psd_settings_get_bool(const psdSettings *settings, const char *setting, int *value);
inline int psd_settings_get_list(const psdSettings *settings, const char *setting, char ***value, int *count);
inline int psd_settings_get_range(const psdSettings *settings, const char *setting, int *min, int *max);
inline int psd_settings_get_group(const psdSettings *settings, const char *setting, psdSettings **value);

inline int psd_settings_set(psdSettings *settings, const char *setting, const char *value);
inline int psd_settings_set_int(psdSettings *settings, const char *setting, int value);
inline int psd_settings_set_bool(psdSettings *settings, const char *setting, int value);
inline int psd_settings_set_list(psdSettings *settings, const char *setting, char * const *values, int num_values);
inline int psd_settings_set_range(psdSettings *settings, const char *setting, int min, int max);

inline int psd_settings_get_2(const psdSettings *settings, const char *section, const char *setting, char **value);
inline int psd_settings_get_int_2(const psdSettings *settings, const char *section, const char *setting, int *value);
inline int psd_settings_get_bool_2(const psdSettings *settings, const char *section, const char *setting, int *value);
inline int psd_settings_get_list_2(const psdSettings *settings, const char *section, const char *setting, char ***value, int *count);
inline int psd_settings_get_range_2(const psdSettings *settings, const char *section, const char *setting, int *min, int *max);
inline int psd_settings_get_group_2(const psdSettings *settings, const char *section, const char *setting, psdSettings **value);

inline int psd_settings_set_2(psdSettings *settings, const char *section, const char *setting, const char *value);
inline int psd_settings_set_int_2(psdSettings *settings, const char *section, const char *setting, int value);
inline int psd_settings_set_bool_2(psdSettings *settings, const char *section, const char *setting, int value);
inline int psd_settings_set_list_2(psdSettings *settings, const char *section, const char *setting, char * const *values, int num_values);
inline int psd_settings_set_range_2(psdSettings *settings, const char *section, const char *setting, int min, int max);

inline int psd_settings_get_3(const psdSettings *settings, const char *section1, const char *section2, const char *setting, char **value);
inline int psd_settings_get_int_3(const psdSettings *settings, const char *section1, const char *section2, const char *setting, int *value);
inline int psd_settings_get_bool_3(const psdSettings *settings, const char *section1, const char *section2, const char *setting, int *value);
inline int psd_settings_get_list_3(const psdSettings *settings, const char *section1, const char *section2, const char *setting, char ***value, int *count);
inline int psd_settings_get_range_3(const psdSettings *settings, const char *section1, const char *section2, const char *setting, int *min, int *max);
inline int psd_settings_get_group_3(const psdSettings *settings, const char *section1, const char *section2, const char *setting, psdSettings **value);

inline int psd_settings_set_3(psdSettings *settings, const char *section1, const char *section2, const char *setting, const char *value);
inline int psd_settings_set_int_3(psdSettings *settings, const char *section1, const char *section2, const char *setting, int value);
inline int psd_settings_set_bool_3(psdSettings *settings, const char *section1, const char *section2, const char *setting, int value);
inline int psd_settings_set_list_3(psdSettings *settings, const char *section1, const char *section2, const char *setting, char * const *values, int num_values);
inline int psd_settings_set_range_3(psdSettings *settings, const char *section1, const char *section2, const char *setting, int min, int max);

inline int psd_settings_get_4(const psdSettings *settings, const char *section1, const char *section2, const char *section3, const char *setting, char **value);
inline int psd_settings_get_int_4(const psdSettings *settings, const char *section1, const char *section2, const char *section3, const char *setting, int *value);
inline int psd_settings_get_bool_4(const psdSettings *settings, const char *section1, const char *section2, const char *section3, const char *setting, int *value);
inline int psd_settings_get_list_4(const psdSettings *settings, const char *section1, const char *section2, const char *section3, const char *setting, char ***value, int *count);
inline int psd_settings_get_range_4(const psdSettings *settings, const char *section1, const char *section2, const char *section3, const char *setting, int *min, int *max);
inline int psd_settings_get_group_4(const psdSettings *settings, const char *section1, const char *section2, const char *section3, const char *setting, psdSettings **value);

inline int psd_settings_set_4(psdSettings *settings, const char *section1, const char *section2, const char *section3, const char *setting, const char *value);
inline int psd_settings_set_int_4(psdSettings *settings, const char *section1, const char *section2, const char *section3, const char *setting, int value);
inline int psd_settings_set_bool_4(psdSettings *settings, const char *section1, const char *section2, const char *section3, const char *setting, int value);
inline int psd_settings_set_list_4(psdSettings *settings, const char *section1, const char *section2, const char *section3, const char *setting, char * const *values, int num_values);
inline int psd_settings_set_range_4(psdSettings *settings, const char *section1, const char *section2, const char *section3, const char *setting, int min, int max);

psdSettings *psd_settings_alloc();
void psd_settings_free(psdSettings *settings);

psdSettings *psd_settings_duplicate(const psdSettings *settings);
psdSettings *psd_settings_merge(const psdSettings *settings1, const psdSettings *settings2);
void psd_settings_print(const psdSettings *settings);
void psd_settings_write(const psdSettings *settings, const char *filename);

int psd_read_settings(const char *filename);

#endif
